bitkeeper revision 1.222 (3eba9f498RAq8VzoEW7GBoEnFA1WGw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 8 May 2003 18:17:45 +0000 (18:17 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 8 May 2003 18:17:45 +0000 (18:17 +0000)
dom0_ops.c:
  Fix domain creation to avoid conflicts in domain-id space.

xen/common/dom0_ops.c

index 7a13d135c5f246c79b915bb5c69d64b59e3710fa..52f8b4b1cd27a8fdde0803b9211d05925c3ddb5c 100644 (file)
 
 extern unsigned int alloc_new_dom_mem(struct task_struct *, unsigned int);
 
+/* Basically used to protect the domain-id space. */
+static spinlock_t create_dom_lock = SPIN_LOCK_UNLOCKED;
+
 static unsigned int get_domnr(void)
 {
     static unsigned int domnr = 0;
-    do { domnr = (domnr+1) & ((1<<20)-1); }
-    while ( find_domain_by_id(domnr) != NULL );
-    return domnr;
+    struct task_struct *p;
+    int tries = 0;
+
+    for ( tries = 0; tries < 1024; tries++ )
+    {
+        domnr = (domnr+1) & ((1<<20)-1);
+        if ( (p = find_domain_by_id(domnr)) == NULL )
+            return domnr;
+        free_task_struct(p);
+    }
+
+    return 0;
 }
 
 static void build_page_list(struct task_struct *p)
@@ -97,16 +109,18 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     {
         struct task_struct *p;
         static unsigned int pro = 0;
-        unsigned int dom = get_domnr();
+        unsigned int dom;
         ret = -ENOMEM;
-
-        if ( dom == 0 ) 
-            break;
+        
+        spin_lock_irq(&create_dom_lock);
+        
+        if ( (dom = get_domnr()) == 0 ) 
+            goto exit_create;
 
         pro = (pro+1) % smp_num_cpus;
         p = do_newdomain(dom, pro);
         if ( p == NULL ) 
-            break;
+            goto exit_create;
 
        if (op.u.newdomain.name[0]) {
          strncpy (p -> name, op.u.newdomain.name, MAX_DOMAIN_NAME);
@@ -117,7 +131,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         if ( ret != 0 ) 
         {
             __kill_domain(p);
-            break;
+            goto exit_create;
         }
 
         build_page_list(p);
@@ -129,6 +143,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
             list_entry(p->pg_head.next, struct pfn_info, list) -
             frame_table;
         copy_to_user(u_dom0_op, &op, sizeof(op));
+
+    exit_create:
+        spin_unlock_irq(&create_dom_lock);
     }
     break;